/**
 * @file keyled.h
 * @brief 按键与LED驱动接口头文件
 * @author 废话文学创始人
 * @version 1.0
 * @date 2024-02-25
 */

#ifndef __KEYLED_H__
#define __KEYLED_H__
#include "main.h"

/**
 * @def LED1_ON
 * @brief 点亮LED1
 */
#ifdef LED1_Pin
#define LED1_ON() HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET)
#define LED1_OFF() HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET)
#define LED1_TOGGLE() HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin)
#endif

/**
 * @def KEY_ON
 * @brief 按键按下状态
 */
#define KEY_ON GPIO_PIN_RESET

/**
 * @def KEY_OFF
 * @brief 按键松开状态
 */
#define KEY_OFF GPIO_PIN_SET

/**
 * @brief 按键结构体定义
 */
typedef struct
{
    GPIO_TypeDef *GPIOx;     /**< 按键对应GPIO端口 */
    uint16_t GPIO_Pin;       /**< 按键对应GPIO引脚 */
    uint32_t KeyMask;        /**< 按键掩码 */
    void (*KeyAction)(void); /**< 按键动作回调函数 */
} KEY;

/**
 * @def KEYNUMMER
 * @brief 支持的按键数量
 */
#define KEYNUMMER 8

/*-------------------------------------------------------------*/
/**
 * @brief KeyValue值的含义说明
 * @note 初始状态            0000 0000 0000 0000 0000 0000 0000 0000---32bit
 * @note K1按下             0000 0000 0000 0000 0000 0000 0000 0001
 * @note K3按下             0000 0000 0000 0000 0000 0000 0000 0100
 * @note K1K3都按下         0000 0000 0000 0000 0000 0000 0000 0101
 * @note 只定义了8个按键，按需添加
 */

/**
 * @def K1_MASK
 * @brief key1 掩码
 */
#define K1_MASK ((uint32_t)0x0001)
/**
 * @def K2_MASK
 * @brief key2 掩码
 */
#define K2_MASK ((uint32_t)0x0002)
/**
 * @def K3_MASK
 * @brief key3 掩码
 */
#define K3_MASK ((uint32_t)0x0004)
/**
 * @def K4_MASK
 * @brief key4 掩码
 */
#define K4_MASK ((uint32_t)0x0008)
/**
 * @def K5_MASK
 * @brief key5 掩码
 */
#define K5_MASK ((uint32_t)0x0010)
/**
 * @def K6_MASK
 * @brief key6 掩码
 */
#define K6_MASK ((uint32_t)0x0020)
/**
 * @def K7_MASK
 * @brief key7 掩码
 */
#define K7_MASK ((uint32_t)0x0040)
/**
 * @def K8_MASK
 * @brief key8 掩码
 */
#define K8_MASK ((uint32_t)0x0080)
/**
 * @def KEY_MASK
 * @brief 所有按键掩码
 */
#define KEY_MASK ((uint32_t)0x00FF)

/**
 * @def IS_KEYMASK
 * @brief 判断按键掩码是否合法
 * @param mask 按键掩码
 */
#define IS_KEYMASK(mask) (((((uint32_t)mask) & GPIO_PIN_MASK) != 0x00u) && ((((uint32_t)mask) & ~GPIO_PIN_MASK) == 0x00u))

/**
 * @brief 注册按键
 * @param GPIOx 按键GPIO端口
 * @param GPIO_Pin 按键GPIO引脚
 * @param KeyMask 按键掩码
 * @param KeyAction 按键动作回调函数
 * @return 注册结果，0为失败，1为成功
 * @note 使用前需要对按键进行注册
 */
uint8_t Key_Register(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t KeyMask, void (*KeyAction)(void));

/**
 * @brief 阻塞方式读取按键
 */
void Key_Read_block(void);

/**
 * @brief 非阻塞方式读取按键
 * @param division 分频参数
 */
void Key_Read_unblock(uint32_t division);

/**
 * @brief 获取按键标志位
 * @return 当前按键标志位
 */
uint32_t Key_Flag_Receive(void);

/**
 * @brief 按键标志位动作处理
 * @param KeyFlag 按键标志位
 */
void Key_Flag_Action(uint32_t KeyFlag);

#endif /*__ KEYLED_H__ */